home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Frameworks
/
TransSkel 3.24
/
Demos
/
C Demos
/
ManyWind
/
ManyWind.c
next >
Wrap
Text File
|
1995-03-21
|
9KB
|
367 lines
/*
* Bug: doesn't properly keep bottom of window from going off screen.
*
* ManyWind -- TransSkel demonstration
*
* This application allows up to twenty windows to be created at once,
* with the New item under the File menu. The name of each window
* appears under the Window menu (which is not created until at least
* one window exists). Selecting the window name from the Window menu
* brings the window to the front. For every window created, Skel is
* told to create a new handler. If the window's close box is clicked,
* the handler removes the window name from the Window menu, disposes
* of the window, and removes itself from the window handler list. If
* the window was the last window, the Window menu handler removes
* itself from the menu handler list.
*
* When the first window is created, a Color menu also appears. This
* allows the color of the content region of the frontmost window to
* be changed. It goes away when the last window is closed.
*
* To quit, select Quit from the File menu or type command-Q.
*
* ManyWind demonstrates dynamic window and menu creation and disposal.
* It also shows how handler procedures may be shared among handlers
* for different windows.
*
* 21 Apr 88 Version 1.00
* - Created. Paul DuBois.
* 29 Jan 89 Version 1.01
* - Conversion for TransSkel 2.0.
* 30 Jan 91 Version 1.02
* - Conversion for TransSkel 3.00.
* 05 Jun 93 Version 1.03
* - Conversion for THINK C 6.0.
* 13 Nov 93
* - Added Close item to file menu.
* 11 Feb 94
* - Minor revisions and bug fixes.
* 15 Feb 94
* - Added item checking for Color and Window menus.
* 21 Feb 94
* - Updated for TransSkel 3.11.
* 21 Mar 95
* - Updated for TransSkel 3.19.
*/
# include "TransSkel.h"
# define maxWind 20 /* maximum number of windows existing at once */
enum /* menu numbers */
{
aMenuNum = skelAppleMenuID, /* Apple menu */
fMenuNum, /* File menu */
wMenuNum, /* Window menu */
cMenuNum /* Color menu */
};
enum /* File menu item numbers */
{
newWind = 1,
closeWind,
/* --- */
quitApp = 4
};
enum /* Color menu items numbers */
{
cWhite = 1,
cLtGray,
cGray,
cDkGray,
cBlack
};
static void MakeWindow(void);
MenuHandle fileMenu;
MenuHandle windowMenu;
MenuHandle colorMenu;
short windCount = 0; /* number of currently existing windows */
long windNum = 0; /* id of last window created */
/* ------------- */
/* Menu handling */
/* ------------- */
static pascal void
DoFileMenu (short item)
{
WindowPtr w;
switch (item)
{
case newWind: /* make a new window */
MakeWindow ();
break;
case closeWind:
SkelClose (FrontWindow ());
break;
case quitApp: /* tell SkelEventLoop() to quit */
SkelStopEventLoop ();
break;
}
}
static pascal void
DoWindowMenu (short item)
{
Str255 iTitle, wTitle;
WindowPtr w;
GetMenuItemText (windowMenu, item, iTitle); /* get window name */
for (w = FrontWindow (); w != nil; w = (WindowPtr) ((WindowPeek)w)->nextWindow)
{
GetWTitle (w, wTitle);
if (EqualString (iTitle, wTitle, false, true))
{
SelectWindow (w);
break;
}
}
}
/*
* Change the background pattern of the frontmost window.
* Ignore if the front window is a DA window.
*/
static pascal void
DoColorMenu (short item)
{
WindowPtr w;
w = FrontWindow ();
if (((WindowPeek) w)->windowKind < 0) return; /* front is DA window */
switch (item)
{
case cWhite: BackPat ((ConstPatternParam) &qd.white); break;
case cLtGray: BackPat ((ConstPatternParam) &qd.ltGray); break;
case cGray: BackPat ((ConstPatternParam) &qd.gray); break;
case cDkGray: BackPat ((ConstPatternParam) &qd.dkGray); break;
case cBlack: BackPat ((ConstPatternParam) &qd.black); break;
}
SetWRefCon (w, item); /* save item number for menu checkmarking */
EraseRect (&w->portRect);
}
static pascal void
DoMClobber (MenuHandle m)
{
DisposeMenu (m);
}
static void
SetItemEnableState (MenuHandle m, short item, Boolean state)
{
if (state)
EnableItem (m, item);
else
DisableItem (m, item);
}
/*
* Adjust menus when mouse click occurs in menu bar.
* File menu:
* - New is enabled if window count hasn't exceeded limit.
* - Close is enabled if there is a window visible.
* Color menu:
* - Check item corresponding to color of frontmost window.
* Window menu:
* - Check item corresponding to frontmost window.
*/
static pascal void
AdjustMenus (void)
{
short nItems, i;
Str255 iTitle, wTitle;
short mark;
SetItemEnableState(fileMenu, newWind, windCount < maxWind);
SetItemEnableState(fileMenu, closeWind, FrontWindow() != (WindowPtr) nil);
if (windCount > 0)
{
for (i = cWhite; i <= cBlack; i++)
{
mark = (GetWRefCon (FrontWindow ()) == i ? checkMark : noMark);
SetItemMark (colorMenu, i, mark);
}
GetWTitle (FrontWindow(), wTitle);
nItems = CountMItems (windowMenu);
for (i = 1; i <= nItems; i++)
{
GetMenuItemText (windowMenu, i, iTitle);
mark = (EqualString (iTitle, wTitle, false, true) ? checkMark : noMark);
SetItemMark (windowMenu, i, mark);
}
}
}
/* --------------- */
/* Window handling */
/* --------------- */
static pascal void
DoWUpdate (Boolean resized)
{
WindowPtr w;
GetPort (&w);
EraseRect (&w->portRect); /* repaint w/background pattern */
}
/*
* Mouse was clicked in close box. Remove the window handler (which
* causes the window to be disposed of), and delete the window title
* from the Window menu. If the window was the last one, delete the
* Window and Color menus entirely.
*
* Skel makes sure the port is pointing to the appropriate window, so
* this procedure can determine which window had its close box clicked,
* without being told explicitly.
*/
static pascal void
DoWClose (void)
{
WindowPtr w;
GetPort (&w); /* window to be closed */
SkelRmveWind (w);
}
/*
* Dispose of window. Skel makes sure the port is pointing to the
* appropriate window, so this procedure can determine which window
* is to be disposed, of without being told explicitly.
*
* Also delete the window title from the Window menu. If the window
* was the last one, delete the Window and Color menus entirely.
*/
static pascal void
DoWClobber (void)
{
WindowPtr w;
short i, mItems;
Str255 iTitle, wTitle;
GetPort (&w); /* window to be closed */
GetWTitle (w, wTitle);
DisposeWindow (w);
if (--windCount == 0)
{
SkelRmveMenu (windowMenu); /* last window - clobber menus */
SkelRmveMenu (colorMenu);
}
else
{
for (i = 1, mItems = CountMItems (windowMenu); i <= mItems; ++i)
{
GetMenuItemText (windowMenu, i, iTitle);
if (EqualString (iTitle, wTitle, false, true))
{
DeleteMenuItem (windowMenu, i);
break;
}
}
}
}
/*
* Make new window. Locate at (100, 100) if no other windows, else
* offset slightly from front window. The window title is the next
* window number (1, 2, 3, ...). If this is the first window, create
* the Window and Color menus. Add the window title as the last item
* of the Window menu.
*
* If the maximum window count is reached, disable New in the
* File menu.
*/
static void
MakeWindow (void)
{
WindowPtr w;
Rect r;
Str255 s;
if ((w = FrontWindow ()) == (WindowPtr) nil)
SetRect (&r, 100, 100, 300, 250);
else
{
SkelGetWindContentRect (w, &r);
OffsetRect (&r, 20, 20);
if (r.left > 480 || r.top > 300) /* keep on screen */
OffsetRect (&r, 40 - r.left, 40 - r.top);
}
NumToString (++windNum, s);
if (SkelQuery (skelQHasColorQD))
w = NewCWindow (nil, &r, s, true, noGrowDocProc, (WindowPtr) -1L, true, 0L);
else
w = NewWindow (nil, &r, s, true, noGrowDocProc, (WindowPtr) -1L, true, 0L);
(void) SkelWindow (w,
nil, /* mouseclicks */
nil, /* key clicks */
DoWUpdate, /* updates */
nil, /* activate/deactivate events */
DoWClose, /* close window, remove from menu */
DoWClobber, /* dispose of window */
nil, /* idle proc */
false); /* irrelevant, since no idle proc */
if (windCount++ == 0) /* if first window, create new menus */
{
colorMenu = NewMenu (cMenuNum, "\pColor");
AppendMenu (colorMenu, "\pWhite;Light Gray;Gray;Dark Gray;Black");
(void) SkelMenu (colorMenu, DoColorMenu, DoMClobber, false, false);
windowMenu = NewMenu (wMenuNum, "\pWindow");
(void) SkelMenu (windowMenu, DoWindowMenu, DoMClobber, false, true);
}
AppendMenu (windowMenu, s);
SetWRefCon (w, cWhite);
}
static void
SetupMenus (void)
{
SkelApple (nil, nil); /* initialize Apple menu */
fileMenu = NewMenu (fMenuNum, "\pFile"); /* make File menu handler */
AppendMenu (fileMenu, "\pNew/N;Close/W;(-;Quit/Q");
(void) SkelMenu (fileMenu, DoFileMenu, DoMClobber, false, true);
SkelSetMenuHook (AdjustMenus);
}
/* ------------ */
/* Main program */
/* ------------ */
int
main (void)
{
SkelInit ((SkelInitParamsPtr) nil); /* initialize */
SetupMenus ();
SkelEventLoop (); /* loop 'til Quit selected */
SkelCleanup (); /* clean up */
}